package com.lebang.configuration.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author Eliohn on 2019/9/2.
 * @version 1.0
 */


@Configuration
@PropertySource(value = "classpath:/application.yml")
@Slf4j
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.jedis.pool.max-wait}")
    private long maxWaitMillis;

    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;

    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxTotal;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.block-when-exhausted}")
    private boolean blockWhenExhausted;
    @Value("${spring.redis.database}")
    private int dbIndex;
    @Autowired
    private RedisKeyExpirationListener messageListener;

    @Bean("xianyu")
    public JedisPool redisPoolFactory()  {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        //链接池中最大连接数
        jedisPoolConfig.setMaxTotal(maxTotal);
        //连接池中最少空闲的连接数
        jedisPoolConfig.setMinIdle(minIdle);
        //链接池中最大空闲的连接数
        jedisPoolConfig.setMaxIdle(maxIdle);
        //连接空闲的最小时间，达到此值后空闲连接将可能会被移除
        jedisPoolConfig.setSoftMinEvictableIdleTimeMillis(1000L*60L*5L);
        //资源池中资源最小空闲时间
        jedisPoolConfig.setMinEvictableIdleTimeMillis(80000);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
        jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
        //空闲资源的检测周期
        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(30000);

        // 是否开启空闲资源监测
        jedisPoolConfig.setTestWhileIdle(true);
        // 是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setJmxEnabled(false);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestOnCreate(true);
        jedisPoolConfig.setTestOnReturn(true);
        return new JedisPool(jedisPoolConfig, host, port, timeout, password, dbIndex);
    }



    /**
     * 监听 redis 事件
     *
     * @param connectionFactory
     * @return
     */
    @Bean(name = "container")
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(listenerAdapter, new ChannelTopic("__keyevent@" + dbIndex + "__:expired"));
        return container;
    }

    @Bean
    MessageListenerAdapter listenerAdapter() {
        return new MessageListenerAdapter(messageListener);
    }


//    Jedis jedis = jedisPool.getResource();
//        jedis.psubscribe(new MyListener(), "listen_open_control");
}